public class Output {

	// M16: relocatable,all 16bits
	// M9 : rel,last 9 bits pgoffset;

	// to object code format
	public static String toObj(Instruction instr) throws AssembleException {
		String ops = instr.getOps();
		String[] operand = instr.getOperand();

		// handle pseudo-op
		if (ops.equals(".ORIG")) {

			String segName = Lines.getSegName();
			while (segName.length() < 6) {
				segName = segName.concat("_");
			}

			String relocate = Lines.isRel() ? "X" : "";

			return "H" + segName + Utilities.intToHex(Lines.getStartingLoc())
					+ Utilities.intToHex(Lines.getSegSize()) + relocate;

		} else if (ops.equals(".END")) {
			// handle undefined symbol.
			if (instr.getOperand()[0] != "") {
				if (operand[0].charAt(0) != 'x') {
					if (SymbTable.getVal(operand[0]) == null
							&& !EXTTable.hasSymb(operand[0])) {
						throw new AssembleException(7, instr.getLineNum(),
								operand[0]);
					}
					return "E"
							+ Utilities.intToHex(SymbTable.getVal(operand[0]));
				} else {
					String addr = operand[0].substring(1);
					while (addr.length() < 4) {
						addr = "0".concat(addr);
					}
					return "E" + addr;
				}
			} else {
				// int i = 0;
				// while (Lines.get(i).getAddr() == -1) {
				// i++;
				// }

				// return "E" + Utilities.intToHex(Lines.get(i).getAddr()) + " "
				// + Lines.get(i).getAddr();
				return "E";
			}
		} else if (ops.equals(".FILL")) {
			Integer val = 0;
			if (operand[0].charAt(0) == '#') {
				val = Integer.parseInt(operand[0].substring(1));
			} else if (operand[0].charAt(0) == 'x') {
				val = Integer.parseInt(operand[0].substring(1), 16);
			} else {
				val = SymbTable.getVal(operand[0]) == null ? 0 : SymbTable
						.getVal(operand[0]);
			}
			// handle undefined symbols.
			if (val == null && !EXTTable.hasSymb(operand[0])) {
				throw new AssembleException(7, instr.getLineNum(), operand[0]);
			}

			return "T" + Utilities.intToHex(instr.getAddr())
					+ Utilities.intToHex(val) + instr.relocate();

		} else if (ops.equals(".EQU")) {
			return null;
		} else if (ops.equals(".BLKW")) {
			return null;
		} else if (ops.equals(".STRZ")) {
			int start = instr.getAddr();
			String val = "";
			for (int i = 1; i < operand[0].length() - 1; i++) {
				val = val + "T" + Utilities.intToHex(start)
						+ Utilities.intToHex(operand[0].charAt(i)) + '\n';
				start++;
			}
			val = val + "T" + Utilities.intToHex(start) + Utilities.intToHex(0);
			return val;
		} else if (ops.equals(".EXT") || ops.equals(".ENT")) {// TODO added for
																// lab3.
			return null;
		} else {
			// handle primitive instructions.
			String mc = machineCode(instr);
			if (mc.equals("invalid operation")) {
				throw new AssembleException(3, instr.getLineNum(),
						instr.getOps());
			}
			return "T" + Utilities.intToHex(instr.getAddr()).toUpperCase()
					+ Utilities.binToHex(machineCode(instr)).toUpperCase()
					+ instr.relocate();
		}

	}

	// to listing file format
	public static String tolst(Instruction instr) throws AssembleException {
		String ops = instr.getOps();
		String[] operand = instr.getOperand();

		// handle pseudo-op
		if (ops.equals(".ORIG")) {
			String segName = Lines.getSegName();
			while (segName.length() < 6) {
				segName = segName.concat("_");
			}
			String listLine = "";
			for (int i = 0; i < 28; i++) {
				listLine += " ";
			}
			listLine = listLine + lineNmRightAlign(instr.getLineNum())
					+ segName + "    " + ".ORIG ";
			if (!Lines.isRel()) {
				listLine += instr.getOperand()[0];
			}
			return listLine;

		} else if (ops.equals(".END")) {

			String listLine = "";
			for (int i = 0; i < 28; i++) {
				listLine += " ";
			}
			listLine = listLine + lineNmRightAlign(instr.getLineNum())
					+ "          " + ".END  " + instr.getOperand()[0];
			return listLine;

		} else if (ops.equals(".FILL")) {

			int val = 0;
			if (operand[0].charAt(0) == '#') {
				val = Integer.parseInt(operand[0].substring(1));
			} else if (operand[0].charAt(0) == 'x') {
				val = Integer.parseInt(operand[0].substring(1), 16);
			} else {
				val = SymbTable.getVal(operand[0]) == null ? 0 : SymbTable
						.getVal(operand[0]);
			}

			String listLine = "(" + Utilities.intToHex(instr.getAddr()) + ") "
					+ Utilities.intToHex(val) + " "
					+ Utilities.toBinary(val, 16);
			listLine = listLine + lineNmRightAlign(instr.getLineNum())
					+ instr.getSymb();

			int numOfSpace = 10 - instr.getSymb().length();
			for (int i = 0; i < numOfSpace; i++) {
				listLine += " ";
			}
			listLine = listLine + ".FILL " + instr.getOperand()[0];

			return listLine;

		} else if (ops.equals(".EQU")) {
			String listLine = "";
			for (int i = 0; i < 28; i++) {
				listLine += " ";
			}
			listLine = listLine + lineNmRightAlign(instr.getLineNum())
					+ instr.getSymb();
			int numOfSpace = 10 - instr.getSymb().length();
			for (int i = 0; i < numOfSpace; i++) {
				listLine += " ";
			}

			listLine = listLine + ".EQU  " + instr.getOperand()[0];
			return listLine;

		} else if (ops.equals(".BLKW")) {

			String listLine = "(" + Utilities.intToHex(instr.getAddr()) + ")";
			for (int i = 0; i < 22; i++) {
				listLine += " ";
			}
			listLine = listLine + lineNmRightAlign(instr.getLineNum())
					+ instr.getSymb();
			int numOfSpace = 10 - instr.getSymb().length();
			for (int i = 0; i < numOfSpace; i++) {
				listLine += " ";
			}
			listLine = listLine + ".BLKW " + instr.getOperand()[0];

			return listLine;

		} else if (ops.equals(".STRZ")) {

			int startLoc = instr.getAddr();

			String listLine = "("
					+ Utilities.intToHex(instr.getAddr())
					+ ") "
					+ Utilities
							.intToHex((int) (instr.getOperand()[0].charAt(1)))
					+ " "
					+ Utilities.toBinary(
							(int) (instr.getOperand()[0].charAt(1)), 16)
					+ lineNmRightAlign(instr.getLineNum()) + instr.getSymb();
			int numOfSpace = 10 - instr.getSymb().length();
			for (int i = 0; i < numOfSpace; i++) {
				listLine += " ";
			}
			listLine = listLine + ".STRZ " + instr.getOperand()[0] + "\n";

			for (int i = 0; i < instr.getOperand()[0].length() - 3; i++) {
				startLoc++;
				listLine = listLine
						+ "("
						+ Utilities.intToHex(startLoc)
						+ ") "
						+ Utilities.intToHex((int) (instr.getOperand()[0]
								.charAt(2 + i)))
						+ " "
						+ Utilities
								.toBinary((int) (instr.getOperand()[0]
										.charAt(2 + i)), 16)
						+ lineNmRightAlign(instr.getLineNum()) + "\n";
			}

			listLine = listLine + "(" + Utilities.intToHex(++startLoc)
					+ ") 0000 0000000000000000"
					+ lineNmRightAlign(instr.getLineNum());
			return listLine;
		} else if (ops.equals(".EXT") || ops.equals(".ENT")) {
			String listLine = "";
			for (int i = 0; i < 28; i++) {
				listLine += " ";
			}
			listLine = listLine + lineNmRightAlign(instr.getLineNum())
					+ instr.getSymb();
			int numOfSpace = 10 - instr.getSymb().length();
			for (int i = 0; i < numOfSpace; i++) {
				listLine += " ";
			}

			listLine = listLine + ops + "  ";
			for (int i = 0; i < instr.getOperand().length; i++) {
				listLine += instr.getOperand()[i] + ",";
			}
			return listLine.substring(0, listLine.length() - 1);
		} else {

			String listLine = "(" + Utilities.intToHex(instr.getAddr()) + ") "
					+ Utilities.binToHex(machineCode(instr)) + " "
					+ machineCode(instr) + lineNmRightAlign(instr.getLineNum())
					+ instr.getSymb();
			int numOfSpace = 10 - instr.getSymb().length();
			for (int i = 0; i < numOfSpace; i++) {
				listLine += " ";
			}
			listLine += instr.getOps();

			numOfSpace = 6 - instr.getOps().length();
			for (int i = 0; i < numOfSpace; i++) {
				listLine += " ";
			}
			if (!instr.getOps().equals("RET")
					&& !(instr.getOps().equals("DBUG"))
					&& !(instr.getOps().equals("NOP"))) {
				for (int i = 0; i < instr.getOperand().length; i++) {
					listLine += instr.getOperand()[i] + " ";
				}
			}

			return listLine;
		}
	}

	private static String lineNmRightAlign(Integer lineNm) {
		// make sure line number are right aligned in the listing file.
		String space = " ";
		String lnNm = lineNm.toString();
		while (lnNm.length() < 4) {
			lnNm = space.concat(lnNm);
		}
		return " (" + lnNm + ") ";
	}

	// convert assembly code to a 16-bit binary machine code.
	private static String machineCode(Instruction instr)
			throws AssembleException {

		String ops = instr.getOps();

		if (ops.equals("LD")) {

			String opcode = "0010";

			String dr = instr.getOperand()[0];
			if (dr.charAt(0) == 'R') {
				dr = Utilities.toBinary(dr.substring(1), 3);
			} else {
				// TODO handle undefined symbol.
				// here example for when relocatable, no symbols shud be used in
				// certain operands.
				if (Lines.isRel()) {
					throw new AssembleException(
							0,
							"Relative symbols are only allowed to use at pgOffset fields when program is relocatable.");
				}

				if (SymbTable.getVal(dr) == null) {
					throw new AssembleException(7, instr.getLineNum(), dr);
				}
				dr = Utilities.toBinary(SymbTable.getVal(dr), 3);
			}

			String pgOffset = instr.getOperand()[1];
			if (pgOffset.charAt(0) == 'x') {
				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset, 16);
				pgOffset = Utilities.toBinary(addr, 9);

			} else if (pgOffset.charAt(0) == '#') {

				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset);
				pgOffset = Utilities.toBinary(addr, 9);
			} else if (pgOffset.charAt(0) == '=') {
				if (pgOffset.charAt(1) == '#') {
					String lit = pgOffset.substring(2);
					int key = Integer.parseInt(lit);
					pgOffset = Utilities.toBinary(LitTable.get(key), 9);
				} else {
					String lit = pgOffset.substring(2);
					int key = Integer.parseInt(lit, 16);
					pgOffset = Utilities.toBinary(LitTable.get(key), 9);
				}
			} else {
				if (SymbTable.hasSym(pgOffset)) {
					Integer addr = SymbTable.getVal(pgOffset);
					pgOffset = Utilities.toBinary(addr, 9);
				} else if (EXTTable.hasSymb(pgOffset)) {
					pgOffset = "000000000";// 9 zeroes.
				} else {
					throw new AssembleException(7, instr.getLineNum(), pgOffset);
				}
			}
			return opcode + dr + pgOffset;

		} else if (ops.equals("LDI")) {

			String opcode = "1010";

			String dr = instr.getOperand()[0];
			if (dr.charAt(0) == 'R') {
				dr = Utilities.toBinary(dr.substring(1), 3);
			} else {
				if (SymbTable.getVal(dr) == null) {
					throw new AssembleException(7, instr.getLineNum(), dr);
				}
				dr = Utilities.toBinary(SymbTable.getVal(dr), 3);
			}

			String pgOffset = instr.getOperand()[1];
			if (pgOffset.charAt(0) == 'x') {
				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset, 16);
				pgOffset = Utilities.toBinary(addr, 9);

			} else if (pgOffset.charAt(0) == '#') {

				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset);
				pgOffset = Utilities.toBinary(addr, 9);
			} else {
				Integer addr;
				if (SymbTable.hasSym(pgOffset)) {
					addr = SymbTable.getVal(pgOffset);
				} else if (EXTTable.hasSymb(pgOffset)) {
					addr = 0;
				} else {
					throw new AssembleException(7, instr.getLineNum(), pgOffset);
				}
				pgOffset = Utilities.toBinary(addr, 9);
			}

			return opcode + dr + pgOffset;

		} else if (ops.equals("LDR")) {

			String opcode = "0110";

			String dr = instr.getOperand()[0];
			if (dr.charAt(0) == 'R') {
				dr = Utilities.toBinary(dr.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(dr) == null) {
					throw new AssembleException(7, instr.getLineNum(), dr);
				}
				dr = Utilities.toBinary(SymbTable.getVal(dr), 3);
			}

			String br = instr.getOperand()[1];
			if (br.charAt(0) == 'R') {
				br = Utilities.toBinary(br.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(br) == null) {
					throw new AssembleException(7, instr.getLineNum(), br);
				}

				br = Utilities.toBinary(SymbTable.getVal(br), 3);

			}

			String index = instr.getOperand()[2];
			if (index.charAt(0) == 'x') {
				index = index.substring(1);
				int val = Integer.parseInt(index, 16);
				index = Utilities.toBinary(val, 6);

			} else if (index.charAt(0) == '#') {

				index = index.substring(1);
				int val = Integer.parseInt(index);
				index = Utilities.toBinary(val, 6);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(index) == null) {
					throw new AssembleException(7, instr.getLineNum(), index);
				}
				int val = SymbTable.getVal(index);
				index = Utilities.toBinary(val, 6);
			}
			return opcode + dr + br + index;

		} else if (ops.equals("LEA")) {
			String opcode = "1110";

			String dr = instr.getOperand()[0];
			if (dr.charAt(0) == 'R') {
				dr = Utilities.toBinary(dr.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(dr) == null) {
					throw new AssembleException(7, instr.getLineNum(), dr);
				}
				dr = Utilities.toBinary(SymbTable.getVal(dr), 3);
			}

			String pgOffset = instr.getOperand()[1];

			if (pgOffset.charAt(0) == '#') {
				String lit = pgOffset.substring(1);
				int key = Integer.parseInt(lit);
				pgOffset = Utilities.toBinary(key, 16).substring(7, 16);
			} else if (pgOffset.charAt(0) == 'x') {
				String lit = pgOffset.substring(1);
				int key = Integer.parseInt(lit, 16);
				pgOffset = Utilities.toBinary(key, 16).substring(7, 16);
			} else {
				// handle undefined symbol.
				if (SymbTable.hasSym(pgOffset)) {
					pgOffset = Utilities.toBinary(SymbTable.getVal(pgOffset),
							16).substring(7, 16);
				} else if (EXTTable.hasSymb(pgOffset)) {
					pgOffset = "000000000"; // 9 zeroes.
				} else {
					throw new AssembleException(7, instr.getLineNum(), pgOffset);
				}
			}

			return opcode + dr + pgOffset;

		} else if (ops.equals("AND")) {

			String opcode = "0101";

			String dr = instr.getOperand()[0];
			if (dr.charAt(0) == 'R') {
				dr = Utilities.toBinary(dr.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(dr) == null) {
					throw new AssembleException(7, instr.getLineNum(), dr);
				}
				dr = Utilities.toBinary(SymbTable.getVal(dr), 3);
			}

			String sr1 = instr.getOperand()[1];
			if (sr1.charAt(0) == 'R') {
				sr1 = Utilities.toBinary(sr1.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(sr1) == null) {
					throw new AssembleException(7, instr.getLineNum(), sr1);
				}
				sr1 = Utilities.toBinary(SymbTable.getVal(sr1), 3);
			}

			String sr2 = instr.getOperand()[2];
			String indicator = "1";
			if (sr2.charAt(0) == 'x' || sr2.charAt(0) == '#') {
				String lit = sr2.substring(1);
				if (sr2.charAt(0) == '#') {
					sr2 = Utilities.toBinary(lit, 5);
				} else {
					sr2 = Utilities.toBinary(Integer.parseInt(lit, 16), 5);
				}
			} else if (sr2.charAt(0) == 'R') {
				indicator = "000";
				sr2 = sr2.substring(1);
				sr2 = Utilities.toBinary(sr2, 3);
			} else {
				int val = SymbTable.getVal(sr2);
				sr2 = Utilities.toBinary(val, 5);
			}

			return opcode + dr + sr1 + indicator + sr2;

		} else if (ops.equals("ADD")) {

			String opcode = "0001";

			String dr = instr.getOperand()[0];
			if (dr.charAt(0) == 'R') {
				dr = Utilities.toBinary(dr.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(dr) == null) {
					throw new AssembleException(7, instr.getLineNum(), dr);
				}
				dr = Utilities.toBinary(SymbTable.getVal(dr), 3);
			}

			String sr1 = instr.getOperand()[1];
			if (sr1.charAt(0) == 'R') {
				sr1 = Utilities.toBinary(sr1.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(sr1) == null) {
					throw new AssembleException(7, instr.getLineNum(), sr1);
				}
				sr1 = Utilities.toBinary(SymbTable.getVal(sr1), 3);
			}

			String sr2 = instr.getOperand()[2];
			String indicator = "1";
			if (sr2.charAt(0) == 'x' || sr2.charAt(0) == '#') {
				String lit = sr2.substring(1);
				if (sr2.charAt(0) == '#') {
					sr2 = Utilities.toBinary(lit, 5);
				} else if (sr2.charAt(0) == 'x') {
					sr2 = Utilities.toBinary(Integer.parseInt(lit, 16), 5);
				}
			} else if (sr2.charAt(0) == 'R') {
				indicator = "000";
				sr2 = sr2.substring(1);
				sr2 = Utilities.toBinary(sr2, 3);
			} else {
				int val = SymbTable.getVal(sr2);
				sr2 = Utilities.toBinary(val, 5);
			}
			return opcode + dr + sr1 + indicator + sr2;

		} else if (ops.substring(0, 2).equals("BR")) {
			String ccr = ops.substring(2);
			String pgOffset = instr.getOperand()[0];
			if (pgOffset.charAt(0) == 'x') {
				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset, 16);
				pgOffset = Utilities.toBinary(addr, 9);

			} else if (pgOffset.charAt(0) == '#') {

				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset);
				pgOffset = Utilities.toBinary(addr, 9);
			} else {
				Integer addr;
				// handle undefined symbol.
				if (SymbTable.hasSym(pgOffset)) {
					addr = SymbTable.getVal(pgOffset);
				} else if (EXTTable.hasSymb(pgOffset)) {
					addr = 0;
				} else {
					throw new AssembleException(7, instr.getLineNum(), pgOffset);
				}

				pgOffset = Utilities.toBinary(addr, 9);
			}

			if (ccr.equals("NZP")) {
				return "0000111" + pgOffset;
			} else if (ccr.equals("N") || ccr.equals("n")) {
				return "0000100" + pgOffset;
			} else if (ccr.equals("Z") || ccr.equals("z")) {
				return "0000010" + pgOffset;
			} else if (ccr.equals("P") || ccr.equals("p")) {
				return "0000001" + pgOffset;
			} else if (ccr.equals("NZ") || ccr.equals("nz")) {
				return "0000110" + pgOffset;
			} else if (ccr.equals("ZP") || ccr.equals("zp")) {
				return "0000011" + pgOffset;
			} else if (ccr.equals("NP") || ccr.equals("np")) {
				return "0000101" + pgOffset;
			} else if (ops.trim().length() == 2) {
				return "0000000" + pgOffset;
			} else {
				return "invalid operation";
			}

		} else if (ops.equals("JSR")) {
			String opcode = "0100100";

			String pgOffset = instr.getOperand()[0];
			if (pgOffset.charAt(0) == 'x') {
				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset, 16);
				pgOffset = Utilities.toBinary(addr, 9);

			} else if (pgOffset.charAt(0) == '#') {

				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset);
				pgOffset = Utilities.toBinary(addr, 9);
			} else {
				Integer addr;
				// handle undefined symbol.
				if (SymbTable.hasSym(pgOffset)) {
					addr = SymbTable.getVal(pgOffset);
				} else if (EXTTable.hasSymb(pgOffset)) {
					addr = 0;
				} else {
					throw new AssembleException(7, instr.getLineNum(), pgOffset);
				}
				pgOffset = Utilities.toBinary(addr, 9);
			}

			return opcode + pgOffset;

		} else if (ops.equals("JSRR")) {
			String opcode = "1100100";

			String br = instr.getOperand()[0];
			String index = instr.getOperand()[1];

			if (br.charAt(0) == 'R') {
				br = Utilities.toBinary(br.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(br) == null) {
					throw new AssembleException(7, instr.getLineNum(), br);
				}
				br = Utilities.toBinary(SymbTable.getVal(br), 3);
			}

			if (index.charAt(0) == 'x') {
				index = index.substring(1);
				int val = Integer.parseInt(index, 16);
				index = Utilities.toBinary(val, 6);

			} else if (index.charAt(0) == '#') {

				index = index.substring(1);
				int val = Integer.parseInt(index);
				index = Utilities.toBinary(val, 6);
			} else {
				Integer val = SymbTable.getVal(index);
				if (val == null) {
					throw new AssembleException(7, instr.getLineNum(), index);
				}
				index = Utilities.toBinary(val, 6);
			}

			return opcode + br + index;
		} else if (ops.equals("JMP")) {

			String opcode = "0100000";

			String pgOffset = instr.getOperand()[0];
			if (pgOffset.charAt(0) == 'x') {
				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset, 16);
				pgOffset = Utilities.toBinary(addr, 9);

			} else if (pgOffset.charAt(0) == '#') {

				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset);
				pgOffset = Utilities.toBinary(addr, 9);
			} else {
				Integer addr;
				// handle undefined symbol.
				if (SymbTable.hasSym(pgOffset)) {
					addr = SymbTable.getVal(pgOffset);
				} else if (EXTTable.hasSymb(pgOffset)) {
					addr = 0;
				} else {
					throw new AssembleException(7, instr.getLineNum(), pgOffset);
				}

				pgOffset = Utilities.toBinary(addr, 9);
			}

			return opcode + pgOffset;

		} else if (ops.equals("ST")) {

			String opcode = "0011";

			String sr = instr.getOperand()[0];

			if (sr.charAt(0) == 'R') {
				sr = Utilities.toBinary(sr.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(sr) == null) {
					throw new AssembleException(7, instr.getLineNum(), sr);
				}
				sr = Utilities.toBinary(SymbTable.getVal(sr), 3);
			}

			String pgOffset = instr.getOperand()[1];
			if (pgOffset.charAt(0) == 'x') {
				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset, 16);
				pgOffset = Utilities.toBinary(addr, 9);

			} else if (pgOffset.charAt(0) == '#') {

				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset);
				pgOffset = Utilities.toBinary(addr, 9);
			} else {
				Integer addr;
				// handle undefined symbol.
				if (SymbTable.hasSym(pgOffset)) {
					addr = SymbTable.getVal(pgOffset);
				} else if (EXTTable.hasSymb(pgOffset)) {
					addr = 0;
				} else {
					throw new AssembleException(7, instr.getLineNum(), pgOffset);
				}

				pgOffset = Utilities.toBinary(addr, 9);
			}

			return opcode + sr + pgOffset;

		} else if (ops.equals("STI")) {
			String opcode = "1011";

			String sr = instr.getOperand()[0];
			if (sr.charAt(0) == 'R') {
				sr = Utilities.toBinary(sr.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(sr) == null) {
					throw new AssembleException(7, instr.getLineNum(), sr);
				}
				sr = Utilities.toBinary(SymbTable.getVal(sr), 3);
			}

			String pgOffset = instr.getOperand()[1];
			if (pgOffset.charAt(0) == 'x') {
				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset, 16);
				pgOffset = Utilities.toBinary(addr, 9);

			} else if (pgOffset.charAt(0) == '#') {

				pgOffset = pgOffset.substring(1);
				int addr = Integer.parseInt(pgOffset);
				pgOffset = Utilities.toBinary(addr, 9);
			} else {
				Integer addr;
				// handle undefined symbol.
				if (SymbTable.hasSym(pgOffset)) {
					addr = SymbTable.getVal(pgOffset);
				} else if (EXTTable.hasSymb(pgOffset)) {
					addr = 0;
				} else {
					throw new AssembleException(7, instr.getLineNum(), pgOffset);
				}

				pgOffset = Utilities.toBinary(addr, 9);
			}

			return opcode + sr + pgOffset;

		} else if (ops.equals("STR")) {

			String opcode = "0111";

			String sr = instr.getOperand()[0];
			if (sr.charAt(0) == 'R') {
				sr = Utilities.toBinary(sr.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(sr) == null) {
					throw new AssembleException(7, instr.getLineNum(), sr);
				}
				sr = Utilities.toBinary(SymbTable.getVal(sr), 3);
			}

			String br = instr.getOperand()[1];
			if (br.charAt(0) == 'R') {
				br = Utilities.toBinary(br.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(br) == null) {
					throw new AssembleException(7, instr.getLineNum(), br);
				}
				br = Utilities.toBinary(SymbTable.getVal(br), 3);
			}

			String index = instr.getOperand()[2];
			if (index.charAt(0) == 'x') {
				index = index.substring(1);
				int val = Integer.parseInt(index, 16);
				index = Utilities.toBinary(val, 6);

			} else if (index.charAt(0) == '#') {

				index = index.substring(1);
				int val = Integer.parseInt(index);
				index = Utilities.toBinary(val, 6);
			} else {
				Integer val = SymbTable.getVal(index);
				// handle undefined symbol.
				if (val == null) {
					throw new AssembleException(7, instr.getLineNum(), index);
				}
				index = Utilities.toBinary(val, 6);
			}
			return opcode + sr + br + index;

		} else if (ops.equals("TRAP")) {
			String opcode = "11110000";

			String trapVect = instr.getOperand()[0];

			if (trapVect.charAt(0) == 'x') {
				int trap = Integer.parseInt(trapVect.substring(1), 16);
				trapVect = Utilities.toBinary(trap, 16).substring(8);

			} else if (trapVect.charAt(0) == '#') {
				trapVect = Utilities.toBinary(trapVect.substring(1), 16)
						.substring(8);
			} else {
				Integer trap = SymbTable.getVal(trapVect);
				// handle undefined symbol.
				if (trap == null) {
					throw new AssembleException(7, instr.getLineNum(), trapVect);
				}
				trapVect = Utilities.toBinary(trap, 16).substring(8);
			}

			return opcode + trapVect;
		} else if (ops.equals("RET")) {
			return "1101000000000000";
		} else if (ops.equals("DBUG")) {
			return "1000000000000000";
		} else if (ops.equals("NOT")) {

			String opcode = "1001";

			String dr = instr.getOperand()[0];
			if (dr.charAt(0) == 'R') {
				dr = Utilities.toBinary(dr.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(dr) == null) {
					throw new AssembleException(7, instr.getLineNum(), dr);
				}
				dr = Utilities.toBinary(SymbTable.getVal(dr), 3);
			}

			String sr = instr.getOperand()[1];
			if (sr.charAt(0) == 'R') {
				sr = Utilities.toBinary(sr.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(sr) == null) {
					throw new AssembleException(7, instr.getLineNum(), sr);
				}
				sr = Utilities.toBinary(SymbTable.getVal(sr), 3);
			}

			return opcode + dr + sr + "111111";

		} else if (ops.equals("JMPR")) {
			String opcode = "1100000";

			String br = instr.getOperand()[0];
			String index = instr.getOperand()[1];

			if (br.charAt(0) == 'R') {
				br = Utilities.toBinary(br.substring(1), 3);
			} else {
				// handle undefined symbol.
				if (SymbTable.getVal(br) == null) {
					throw new AssembleException(7, instr.getLineNum(), br);
				}
				br = Utilities.toBinary(SymbTable.getVal(br), 3);
			}

			if (index.charAt(0) == 'x') {
				index = index.substring(1);
				int val = Integer.parseInt(index, 16);
				index = Utilities.toBinary(val, 6);

			} else if (index.charAt(0) == '#') {

				index = index.substring(1);
				int val = Integer.parseInt(index);
				index = Utilities.toBinary(val, 6);
			} else {
				Integer val = SymbTable.getVal(index);
				// handle undefined symbol.
				if (val == null) {
					throw new AssembleException(7, instr.getLineNum(), index);
				}
				index = Utilities.toBinary(val, 6);
			}

			return opcode + br + index;
		} else if (ops.equals("NOP")) {
			return "0000000000000000";
		} else if (ops.equals(".EXT") || ops.equals(".ENT")) {// TODO added for
																// lab3.
			return "";
		} else {
			return "invalid operation";
		}
	}
}
